[% setvar title Implicit counter in for statements, possibly $#. %]
<div id="archive-notice">
    <h3>This file is part of the Perl 6 Archive</h3>
    <p>To see what is currently happening visit <a href="http://www.perl6.org/">http://www.perl6.org/</a></p>
</div>
<div class='pod'>
<a name='TITLE'></a><h1>TITLE</h1>
<p>Implicit counter in for statements, possibly $#.</p>
<a name='VERSION'></a><h1>VERSION</h1>
<pre>  Maintainer: John McNamara &lt;<a href='mailto:jmcnamara@cpan.org'>jmcnamara@cpan.org</a>&gt;
  Date: 16 Aug 2000
  Last Modified: 27 Sep 2000
  Mailing List: <a href='mailto:perl6-language-flow@perl.org'>perl6-language-flow@perl.org</a>
  Number: 120
  Version: 5
  Status: Frozen
  Frozen since: v3</pre>
<a name='ABSTRACT'></a><h1>ABSTRACT</h1>
<p>The syntax of the Perl style <code>for</code> statement could be augmented by the
introduction of an implicit counter variable. The deprecated variable
<code>$#</code> could be used for this purpose due to its mnemonic association
with <code>$#array</code>.</p>
<p>Other alternatives are also proposed: an explicit counter returned by a
function; an explicit counter defined after foreach; an explicit counter
defined by a scoping statement.</p>
<a name='DESCRIPTION'></a><h1>DESCRIPTION</h1>
<p>The use of <code>for</code> and <code>foreach</code> statements in conjunction with the
range operator, <code>..</code>, are generally seen as good idiomatic Perl:</p>
<pre>    @array = qw(sun moon stars rain);
    
    foreach $item (@array) {
        print $item, &quot;\n&quot;;
    }</pre>
<p>as opposed to the &quot;endearing attachment to C&quot; style:</p>
<pre>    for ($i = 0; $i &lt;= $#array; $i++) {
        print $array[$i], &quot;\n&quot;;
    }</pre>
<p>In particular, the foreach statement provides a useful level of
abstraction when iterating over an array of objects:</p>
<pre>    foreach $object (@array) {
        $object-&gt;getline;
        $object-&gt;parseline;
        $object-&gt;printline;
    }</pre>
<p>However, the abstraction breaks down as soon as there is a need to access
the index as well as the variable:</p>
<pre>    for ($i = 0; $i &lt;= $#array; $i++) { # Note
        $array[$i]-&gt;index = $i;
        $array[$i]-&gt;getline;
        $array[$i]-&gt;parseline;
        $array[$i]-&gt;printline;
    }
    
    # Note - same applies to: foreach $i (0..$#array)</pre>
<p>Here we are dealing with array variables and indexes instead of objects.</p>
<p>The addition of an implicit counter variable in <code>for</code> statements would
lead to a more elegant syntax. It is proposed the deprecated variable
<code>$#</code> should be used for this purpose due to its mnemonic association
with <code>$#array</code>. For example:</p>
<pre>    foreach $item (@array) {
        print $item, &quot; is at index &quot;, $#, &quot;\n&quot;;
    }</pre>
<a name='ALTERNATIVE METHODS'></a><h1>ALTERNATIVE METHODS</h1>
<p>Following discussion of this proposal on perl6-language-flow the following
suggestions were made:</p>
<a name='Alternative 1 : Explicit counter returned by a function'></a><h2>Alternative 1 : Explicit counter returned by a function</h2>
<p>This was proposed by Mike Pastore who suggested reusing pos() and by
Hildo Biersma who suggested using position():</p>
<pre>    foreach $item (@array) {
        print $item, &quot; is at index &quot;, pos(@array), &quot;\n&quot;;
    }
    
    # or:
    
    foreach $item (@array) {
        $index = some_counter_function();   
        print $item, &quot; is at index &quot;, $index, &quot;\n&quot;;
    }</pre>
<a name='Alternative 2 : Explicit counter defined after foreach'></a><h2>Alternative 2 : Explicit counter defined after foreach</h2>
<p>This was proposed by Chris Madsen and Tim Jenness, Jonathan Scott Duff
made a similar pythonesque suggestion:</p>
<pre>    foreach $item, $index (@array) {
        print $item, &quot; is at index &quot;, $index, &quot;\n&quot;;
    }
    </pre>
<p>Glenn Linderman added this could also be used for hashes:</p>
<pre>    foreach $item $key ( %hash ) {
        print &quot;$item is indexed by $key\n&quot;;
    }</pre>
<p>Ariel Scolnicov suggested a variation on this through an extension of
the <code>each()</code>:</p>
<pre>    while (($item, $index) = each(@array)) {
        print $item, &quot; is at index &quot;, $index, &quot;\n&quot;;
    }</pre>
<p>With this in mind Johan Vromans suggested the use of <code>keys()</code> and
<code>values()</code> on arrays.</p>
<p>A variation on this is an explicit counter after <code>@array</code>. This was
alluded to by Jonathan Scott Duff:</p>
<pre>    foreach $item (@array) $index {
        print $item, &quot; is at index &quot;, $index, &quot;\n&quot;;
    }</pre>
<a name='Alternative 3 : Explicit counter defined by a scoping statement'></a><h2>Alternative 3 : Explicit counter defined by a scoping statement</h2>
<p>This was proposed by Nathan Torkington. This behaves somewhat similarly
to Tie::Counter.</p>
<pre>    foreach $item (@array) {
        my $index : static = 0; # initialized each time foreach loop starts
        print &quot;$item is at index $index\n&quot;;
        $index++;
    }
    
    # or: 

    foreach $item (@array) {
        my $index : counter = 0; # initialized to 0 first time
                                 # incremented by 1 subsequently
        print &quot;$item is at index $index\n&quot;;
    }</pre>
<a name='IMPLEMENTATION'></a><h1>IMPLEMENTATION</h1>
<p>There was no discussion about how this might be implemented. It was
pointed out by more than one person it would inevitably incur an
overhead.</p>
<a name='REFERENCES'></a><h1>REFERENCES</h1>
<p>perlvar</p>
<p>Alex Rhomberg proposed an implicit counter variable on clpm:
<a href='http://x53.deja.com/getdoc.xp?AN=557218804' target='_blank'>x53.deja.com</a>&amp;fmt=text and
<a href='http://x52.deja.com/threadmsg_ct.xp?AN=580369190.1' target='_blank'>x52.deja.com</a>&amp;fmt=text</p>
<p>Craig Berry suggested <code>$#</code>:
<a href='http://x52.deja.com/threadmsg_ct.xp?AN=580403316.1' target='_blank'>x52.deja.com</a>&amp;fmt=text</p>
</div>
